﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="SendXsltTransformedEmailExtended.cs" company="Open Source">
//   MIT License
// </copyright>
// <summary>
//   The Extended "send email" workflow type.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace Contour.Contrib.WorkflowTypes
{
    using System;
    using System.Collections.Generic;
    using System.Net.Mail;
    using System.Xml;
    using System.Text;

    using System.Linq;
    using System.Web.Configuration;

    using umbraco;

    using Umbraco.Forms.Core;
    using Umbraco.Forms.Core.Attributes;
    using Umbraco.Forms.Core.Enums;
    using Umbraco.Forms.Data;
    using Umbraco.Forms.Data.Storage;

    /// <summary>
    /// The send email.
    /// </summary>
    public class SendEmail : WorkflowType
    {
        #region Constructors and Destructors

        /// <summary>
        /// Initializes a new instance of the <see cref="SendEmail"/> class.
        /// </summary>
        public SendEmail()
        {
            this.Id = new Guid("5E6A5333-1E33-41F9-A292-69BD7578DE0C");
            this.Name = "Send xslt transformed email, extended";
            this.Description =
                "Send the result of the form to 1 or multiple email addresses (separated with a semi-colon: ';'). To reference a field from your form use a lowercase, spaceless version of your field name inside curly brackets like: {emailaddress}.";
        }

        #endregion

        #region Properties

        /// <summary>
        /// Gets or sets Attachment.
        /// </summary>
        [Setting("Attachment", description = "Attach file uploads to email", 
            control = "Umbraco.Forms.Core.FieldSetting.Checkbox")]
        public string Attachment { get; set; }

        /// <summary>
        /// Gets or sets Email.
        /// </summary>
        [Setting("Email", description = "Enter the receiver email", 
            control = "Umbraco.Forms.Core.FieldSetting.TextField")]
        public string Email { get; set; }

        /// <summary>
        /// Gets or sets From Email.
        /// </summary>
        [Umbraco.Forms.Core.Attributes.Setting("From Email", description = "Enter the from email (optional)", control = "Umbraco.Forms.Core.FieldSetting.TextField")]
        public string FromEmail { get; set; }

        /// <summary>
        /// Gets or sets From Name.
        /// </summary>
        [Umbraco.Forms.Core.Attributes.Setting("From Name", description = "Enter the from name (optional)", control = "Umbraco.Forms.Core.FieldSetting.TextField")]
        public string FromName { get; set; }

        /// <summary>
        /// Gets or sets ReplyTo.
        /// </summary>
        [Setting("ReplyTo", description = "Enter the reply-to email", 
            control = "Umbraco.Forms.Core.FieldSetting.TextField")]
        public string ReplyTo { get; set; }

        /// <summary>
        /// Gets or sets Subject.
        /// </summary>
        [Setting("Subject", description = "Enter the subject", control = "Umbraco.Forms.Core.FieldSetting.TextField")]
        public string Subject { get; set; }

        /// <summary>
        /// Gets or sets XsltFile.
        /// </summary>
        [Setting("XsltFile",
            description =
                "Transform the xml before posting it,<a target='_blank' href='xslt/postAsXmlSample.xslt'>(Sample file)</a>",
            prevalues = "XsltEmail", 
            control = "Umbraco.Forms.Core.FieldSetting.File")]
        public string XsltFile { get; set; }

        #endregion

        #region Public Methods

        /// <summary>
        /// Execute the workflow step
        /// </summary>
        /// <param name="record">
        /// The record.
        /// </param>
        /// <param name="e">
        /// The record event arguments
        /// </param>
        /// <returns>
        /// The workflow execution stutus
        /// </returns>
        public override WorkflowExecutionStatus Execute(Record record, RecordEventArgs e)
        {
            MailAddress FromMailAddress;
            if (string.IsNullOrEmpty(this.FromEmail))
            {
                FromMailAddress = new MailAddress(UmbracoSettings.NotificationEmailSender);
            }
            else
            {
                if (string.IsNullOrEmpty(this.FromName))
                {
                    FromMailAddress = new MailAddress(this.FromEmail);
                }
                else
                {
                    FromMailAddress = new MailAddress(this.FromEmail, this.FromName);
                }
            }
            var mailMessage = new MailMessage
                {
                    From = FromMailAddress, 
                    Subject = this.Subject, 
                    ReplyTo = new MailAddress(this.ReplyTo),
                    IsBodyHtml = true,
                    BodyEncoding = Encoding.UTF8
                };

            if (this.Email.Contains(";"))
            {
                foreach (string email in this.Email.Split(';'))
                {
                    mailMessage.To.Add(email.Trim());
                }
            }
            else
            {
                mailMessage.To.Add(this.Email);
            }

            var viewer = new RecordsViewer();
            XmlNode xml = viewer.GetSingleXmlRecord(record, new XmlDocument());

            if (this.Attachment == true.ToString())
            {
                WorkflowHelper.AddAttachmentToMail(mailMessage, xml);
            }

            // we will by default set the body to the record xml so if no xslt file is
            // present we atleast get the raw data.
            string result = xml.OuterXml;
            if (!string.IsNullOrEmpty(this.XsltFile))
            {
                result = XsltHelper.TransformXML(xml, this.XsltFile, null);
            }

            mailMessage.Body = result;

            var smtpClient = new SmtpClient { EnableSsl = false };

            if (WebConfigurationManager.AppSettings.AllKeys.Contains("contourContribUseSsl") && WebConfigurationManager.AppSettings["contourContribUseSsl"].ToLower() == true.ToString().ToLower())
            {
                smtpClient.EnableSsl = true;
            }

            smtpClient.Send(mailMessage);

            return WorkflowExecutionStatus.Completed;
        }

        /// <summary>
        /// The validate settings.
        /// </summary>
        /// <returns>
        /// A list of exceptions.
        /// </returns>
        public override List<Exception> ValidateSettings()
        {
            var exceptions = new List<Exception>();
            if (string.IsNullOrEmpty(this.ReplyTo))
            {
                exceptions.Add(new Exception("'Reply-to' setting not filled out'"));
            }

            if (string.IsNullOrEmpty(this.Email))
            {
                exceptions.Add(new Exception("'Email' setting not filled out'"));
            }

            if (string.IsNullOrEmpty(this.Subject))
            {
                exceptions.Add(new Exception("'Subject' setting not filled out'"));
            }

            return exceptions;
        }

        #endregion
    }
}